﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WmsApp.WindowControl
{
    ///<summary>
    /// 数字转换成大写金额 例：(new MoneyToChineseChanger(200)).ToString() == "贰佰元"
    /// </summary>
    public sealed class MoneyToChineseChanger 
    {
        /// <summary>
        /// 人民币符号
        /// </summary>
        private const string Rmb = "￥";
        #region 对外属性
        public string 分
        {
            get
            {
                string tmp = InvertString(Math.Round((Decimal)this.money100, 0).ToString()) + "          ";
                return tmp[0].ToString();
            }
        }

        public string 角
        {
            get
            {
                string tmp = InvertString(Math.Round((Decimal)this.money100, 0).ToString()) + "          ";
                if (!String.IsNullOrEmpty(tmp[0].ToString().Trim()) && String.IsNullOrEmpty(tmp[1].ToString().Trim()))
                {
                    return Rmb;
                }
                return tmp[1].ToString();
            }
        }

        public string 元
        {
            get
            {
                string tmp = InvertString(Math.Round((Decimal)this.money100, 0).ToString()) + "          ";
                if (!String.IsNullOrEmpty(tmp[1].ToString().Trim()) && String.IsNullOrEmpty(tmp[2].ToString().Trim()))
                {
                    return Rmb;
                }
                return tmp[2].ToString();
            }
        }

        public string 十
        {
            get
            {
                string tmp = InvertString(Math.Round((Decimal)this.money100, 0).ToString()) + "          ";
                if (!String.IsNullOrEmpty(tmp[2].ToString().Trim()) && String.IsNullOrEmpty(tmp[3].ToString().Trim()))
                {
                    return Rmb;
                }
                return tmp[3].ToString();
            }
        }

        public string 佰
        {
            get
            {
                string tmp = InvertString(Math.Round((Decimal)this.money100, 0).ToString()) + "          ";
                if (!String.IsNullOrEmpty(tmp[3].ToString().Trim()) && String.IsNullOrEmpty(tmp[4].ToString().Trim()))
                {
                    return Rmb;
                }
                return tmp[4].ToString();
            }
        }

        public string 仟
        {
            get
            {
                string tmp = InvertString(Math.Round((Decimal)this.money100, 0).ToString()) + "          ";
                if (!String.IsNullOrEmpty(tmp[4].ToString().Trim()) && String.IsNullOrEmpty(tmp[5].ToString().Trim()))
                {
                    return Rmb;
                }
                return tmp[5].ToString();
            }
        }

        public string 万
        {
            get
            {
                string tmp = InvertString(Math.Round((Decimal)this.money100, 0).ToString()) + "          ";
                if (!String.IsNullOrEmpty(tmp[5].ToString().Trim()) && String.IsNullOrEmpty(tmp[6].ToString().Trim()))
                {
                    return Rmb;
                }
                return tmp[6].ToString();
            }
        }

        public string 十万
        {
            get
            {
                string tmp = InvertString(Math.Round((Decimal)this.money100, 0).ToString()) + "          ";
                if (!String.IsNullOrEmpty(tmp[6].ToString().Trim()) && String.IsNullOrEmpty(tmp[7].ToString().Trim()))
                {
                    return Rmb;
                }
                return tmp[7].ToString();
            }
        }

        public string 佰万
        {
            get
            {
                string tmp = InvertString(Math.Round((Decimal)this.money100, 0).ToString()) + "          ";
                if (!String.IsNullOrEmpty(tmp[7].ToString().Trim()) && String.IsNullOrEmpty(tmp[8].ToString().Trim()))
                {
                    return Rmb;
                }
                return tmp[8].ToString();
            }
        }

        private string InvertString(string s)
        {
            if (String.IsNullOrEmpty(s))
                return "";
            char[] charstr = s.ToCharArray();
            Array.Reverse(charstr);
            return new string(charstr);
        }
        #endregion

        #region 字段
        /// <summary>
        /// 大写数字
        /// </summary>
        public const string Digit = "零壹贰叁肆伍陆柒捌玖";

        private bool overFlow;
        /// <summary>
        /// 金额*100，即以“分”为单位的金额
        /// </summary>
        private long money100;
        /// <summary>
        /// 片段内是否全零
        /// </summary>
        private bool isAllZero;
        /// <summary>
        /// 第一位数字是否是零
        /// </summary>
        private bool isPreZero;
        private string yuan;
        private string jiao;
        private string fen;
        private string zheng;
        private StringBuilder sb;
        #endregion

        #region 属性
        /// <summary>
        /// “元”，可以改为“圆”、“卢布”之类
        /// </summary>
        public string Yuan
        {
            set { yuan = value; }
            get { return yuan; }
        }
        /// <summary>
        /// “角”，可以改为“拾”
        /// </summary>
        public string Jiao
        {
            set { jiao = value; }
            get { return jiao; }
        }
        /// <summary>
        /// “分”，可以改为“美分”之类
        /// </summary>
        public string Fen
        {
            set { fen = value; }
            get { return fen; }
        }

        /// <summary>
        /// “整”
        /// </summary>
        public string Zheng
        {
            set { zheng = value; }
            get { return zheng; }
        }

        /// <summary>
        /// 零元
        /// </summary>
        public string ZeroString
        {
            get { return Digit[0] + yuan; }
        }
        /// <summary>
        /// 溢出标志
        /// </summary>
        public bool OverFlow
        {
            get { return overFlow; }
        }
        #endregion

        public MoneyToChineseChanger()
        {
            isPreZero = isAllZero = true;
            yuan = "元";
            jiao = "角";
            fen = "分";
            zheng = "整";
            sb = new StringBuilder();
        }
        public MoneyToChineseChanger(decimal money)
            : this()
        {
            SetMoney(money);
        }

        /// <summary>
        /// 解析“片段”: “角分(2位)”或“万以内的一段(4位)”
        /// </summary>
        /// <param name="isJiaoFen"></param>
        private void ParseSection(bool isJiaoFen, ref long abs)
        {
            string[] Unit = isJiaoFen ? new string[] { fen, jiao } : new string[] { String.Empty, "拾", "佰", "仟" };
            isAllZero = true;
            for (int i = 0; i < Unit.Length && abs > 0; i++)
            {
                int d = (int)(abs % 10);
                if (d != 0)
                {
                    if (isPreZero && !isAllZero)
                    {
                        sb.Append(Digit[0]);
                    }
                    sb.AppendFormat("{0}{1}", Unit[i], Digit[d]);
                    isAllZero = false;
                }
                isPreZero = (d == 0);
                abs /= 10;
            }
        }

        public MoneyToChineseChanger SetMoney(decimal money)
        {
            try
            {
                money100 = (long)(money * 100m);
            }
            catch
            {
                overFlow = true;
            }
            if (money100 == long.MinValue)
            {
                overFlow = true;
            }
            return this;
        }

        /// <summary>
        /// 重载 ToString() 方法
        /// </summary>
        /// <returns>大写金额字符串</returns>
        public override string ToString()
        {
            if (overFlow)
            {
                return "金额超出范围";
            }
            if (money100 == 0)
            {
                return this.ZeroString;
            }
            sb.Remove(0, sb.Length);
            string[] Unit = { yuan, "万", "亿", "万", "亿亿" };
            long moneyAbs = Math.Abs(money100);
            ParseSection(true, ref moneyAbs);
            for (int i = 0; i < Unit.Length && moneyAbs > 0; i++)
            {
                if (isPreZero && !isAllZero)
                {
                    sb.Append(Digit[0]);
                }
                if (i == 4 && sb.ToString().EndsWith(Unit[2]))
                {
                    sb.Remove(sb.Length - Unit[2].Length, Unit[2].Length);
                }
                sb.Append(Unit[i]);
                ParseSection(false, ref moneyAbs);
                if ((i % 2) == 1 && isAllZero)
                {
                    sb.Remove(sb.Length - Unit[i].Length, Unit[i].Length);
                }
            }
            if (money100 < 0)
            {
                sb.Append("负");
            }
            //反转字符串
            Char[] charArray = sb.ToString().ToCharArray();
            Array.Reverse(charArray);

            var tmp = new String(charArray);
            if (tmp.EndsWith(yuan))
            {
                return tmp + zheng;
            }
            return tmp;
        }
    }
}
